package utils

import (
	"crypto/sha256"
	"encoding/base64"
	"encoding/json"
	"fmt"
	"math"
	"math/rand"
	"reflect"
	"time"
)

import (
	"github.com/gin-gonic/gin"
	"net/http"
)

func Throw(err error) {
	if err != nil {
		panic(err)
	}
}

const prefixName = "kerenuser_"
const fixedStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" // 固定字符串

type RespModel struct {
	Code    int         `json:"code"`
	Message string      `json:"msg"`
	Data    interface{} `json:"data"`
}

// ResponseOK 请求成功返回
func ResponseOK(c *gin.Context, data interface{}) {
	d := RespModel{
		Code:    0,
		Message: "ok",
		Data:    data,
	}
	c.JSON(http.StatusOK, d)
}

func ToJsonString(data interface{}) string {
	return string(toJson(data))
}

func ToJsonBytes(data interface{}) []byte {
	return toJson(data)
}

func toJson(data interface{}) []byte {
	if data == nil {
		return nil
	}
	marshal, _ := json.Marshal(data)
	return marshal
}

// ToMap 结构体转为Map[string]interface{}
func ToMap(in interface{}) (map[string]interface{}, error) {
	out := make(map[string]interface{})

	v := reflect.ValueOf(in)
	if v.Kind() == reflect.Ptr {
		v = v.Elem()
	}

	if v.Kind() != reflect.Struct { // 非结构体返回错误提示
		return nil, fmt.Errorf("ToMap only accepts struct or struct pointer; got %T", v)
	}

	t := v.Type()
	// 遍历结构体字段
	// 指定tagName值为map中key;字段值为map中value
	for i := 0; i < v.NumField(); i++ {
		fi := t.Field(i)
		if tagValue := fi.Tag.Get("json"); tagValue != "" {
			out[tagValue] = v.Field(i).Interface()
		}
	}
	return out, nil
}

// PageUtil 分页工具
func PageUtil(size, index int) (int, int) {
	if index == 0 {
		index = 1
	}
	if size <= 0 {
		size = 10
	}
	if size > 1000 {
		size = 1000
	}
	return size, index
}

// EncryptionSha256 密码加密
func EncryptionSha256(password, salt string) string {
	str := fmt.Sprintf("%s%s", password, salt)
	return base64.RawURLEncoding.EncodeToString(sha256.New().Sum([]byte(str)))
}

func PageCount(total, pageSize int64) int64 {
	return int64(math.Ceil(float64(total) / float64(pageSize)))
}

func UserName() string {
	return fmt.Sprint(prefixName, time.Now().Unix())
}

func RandString(count int) string {
	rand.Seed(time.Now().UnixNano()) // 使用当前时间作为随机数种子
	var result string                // 存储结果的字符串
	for i := 0; i < count; i++ {
		result += string(fixedStr[rand.Intn(len(fixedStr))]) // 从固定字符串中随机选择一个字符
	}
	return result
}
